<?php

/**
 * 验证码发送(可切换短信服务商)
 * @author zhouyang(zhouyang@sdxxtop.com)
 * @time   : 2018-02-27 16:15
 */

namespace app\api\help;

class SendMsg
{
    //阿里云短信验证码参数(企业账号)
    const ALI_KEY_ID     = 'LTAI5tRr1LT9Bm5vy9xPv1Ch';
    const ALI_KEY_SECRET = 'GzujL5PX91mGTv2TNEMk7jTEKSyjy2';
    const ALI_DOMAN      = 'dysmsapi.aliyuncs.com';               //短信接口所在域名
    static $temp_code = 'SMS_276436894';                          //短信模板code
    //阿里云推广短信账号参数
    
    
    /**
     * 发短信入口
     * @param int   $mobile
     * @param array $msg 参数
     * @example 发送验证码 sendMsg('17608474053',['code'=>1678],1)
     * @example 账号激活   sendMsg('17608474053',['company'=>'荫田中心校','username'=>'17608474053','password'=>'878263'],2)
     */
    public static function sendMsg($mobile, $msg, $code)
    {
        
        
        $aliSignName = "登楼量贩精品";
        
        //阿里
        $ret = self::aliyun($mobile, $msg, $aliSignName, $code);
        return $ret;
    }
    
    /**
     * 阿里云发送短信
     * @param        $mobile
     * @param        $msg
     * @param string $aliSignName
     * @return bool
     */
    public static function aliyun($mobile, $msg, $aliSignName, $code = '')
    {
        if (empty($code)) {
            $code = self::$temp_code;
        }
        
        $param = [
            'PhoneNumbers' => $mobile,
            'SignName'     => $aliSignName,
            'TemplateCode' => $code,
            'RegionId'     => 'cn-hangzhou',
            'Action'       => 'SendSms',
            'Version'      => '2017-05-25',
        ];
        if ( !empty($msg) && is_array($msg)) {
            $msg = json_encode($msg, JSON_UNESCAPED_UNICODE);
            
            $param[ 'TemplateParam' ] = (string) $msg;
        }
        $url = self::createAliyunSign($param);
        
        //请求短信发送接口
        for ($i = 1 ; $i <= 3 ; $i++) {
            $api_response = self::aliyunHttp($url);
            $api_response = json_decode($api_response, true);
            if ( !empty($api_response) && isset($api_response[ 'Code' ]) && $api_response[ 'Code' ] == 'OK') {
                break;
            }
            usleep(200000); //暂停0.2秒
        }
        //解析接口数据
        if (isset($api_response[ 'Code' ]) && $api_response[ 'Code' ] == 'OK') {
            return true;
        } else {
            return false;
        }
    }
    
    /**
     * 生成阿里云短信签名并拼接
     * @param $domain   string API接口所在域名
     * @param $params   array API具体参数
     * @param $security boolean 使用https
     * @return $url 返回凭借好参数的请求地址
     */
    public static function createAliyunSign($param, $security = false)
    {
        $apiParams = array_merge([
            "SignatureMethod"  => "HMAC-SHA1",
            "SignatureNonce"   => uniqid(mt_rand(0, 0xffff), true),
            "SignatureVersion" => "1.0",
            "AccessKeyId"      => self::ALI_KEY_ID,
            "Timestamp"        => gmdate("Y-m-d\TH:i:s\Z"),
            "Format"           => "JSON",
        ], $param);
        ksort($apiParams);
        
        $sortedQueryStringTmp = "";
        foreach ($apiParams as $key => $value) {
            $sortedQueryStringTmp .= "&" . self::encode($key) . "=" . self::encode($value);
        }
        
        $stringToSign = "GET&%2F&" . self::encode(substr($sortedQueryStringTmp, 1));
        $sign         = base64_encode(hash_hmac("sha1", $stringToSign, self::ALI_KEY_SECRET . "&", true));
        $signature    = self::encode($sign);
        $url          = ($security ? 'https' : 'http') . "://" . self::ALI_DOMAN . "/?Signature={$signature}{$sortedQueryStringTmp}";
        
        return $url;
    }
    
    /**
     * 替换特殊字符
     * @param $str
     * @return null|string|string[]
     */
    public static function encode($str)
    {
        $res = urlencode($str);
        $res = preg_replace("/\+/", "%20", $res);
        $res = preg_replace("/\*/", "%2A", $res);
        $res = preg_replace("/%7E/", "~", $res);
        return $res;
    }
    
    /**
     * 阿里云短信接口发送请求
     * @param $url
     */
    public static function aliyunHttp($url)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "x-sdk-client" => "php/2.0.0",
        ]);
        
        if (substr($url, 0, 5) == 'https') {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }
        
        $rtn = curl_exec($ch);
        
        /* 注释掉产生的用户级别提示信息
        if($rtn === false) {
            trigger_error("[CURL_" . curl_errno($ch) . "]: " . curl_error($ch), E_USER_ERROR);
        }*/
        
        curl_close($ch);
        return $rtn;
    }
}
